package cn.sc.summer.gateway.listener;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpRequest;
import com.alibaba.nacos.client.naming.event.InstancesChangeEvent;
import com.alibaba.nacos.common.notify.NotifyCenter;
import com.alibaba.nacos.common.notify.listener.Subscriber;
import cn.sc.summer.constant.project.ProjectConstant;
import cn.sc.summer.constant.warmup.WarmUpConstant;
import cn.sc.summer.token.util.HeaderUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.cache.Cache;
import org.springframework.cloud.loadbalancer.cache.LoadBalancerCacheManager;
import org.springframework.cloud.loadbalancer.core.CachingServiceInstanceListSupplier;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

/**
 * 类名：nacos服务上下线监听器
 *
 * @author a-xin
 * @date 2023/12/6 16:26
 */
@Slf4j
@Component
public class NacosInstancesChangeEventListener extends Subscriber<InstancesChangeEvent> {

    @Resource
    private ApplicationContext applicationContext;

    @PostConstruct
    public void registerToNotifyCenter() {
        NotifyCenter.registerSubscriber(this);
    }

    @Override
    public void onEvent(InstancesChangeEvent event) {
        String serviceName = event.getServiceName().split("@@")[1];
        if (!serviceName.equals(ProjectConstant.SERVER_NAME)) {
            log.warn("==> SpringCloud Gateway microservice instance refresh event: {}", event.getServiceName());

            ObjectProvider<LoadBalancerCacheManager> cacheManagerProvider = applicationContext.getBeanProvider(LoadBalancerCacheManager.class);
            Cache cache = cacheManagerProvider.getIfAvailable().getCache(CachingServiceInstanceListSupplier.SERVICE_INSTANCE_CACHE_NAME);
            if (ObjectUtil.isNotNull(cache )) {
                boolean present = cache.evictIfPresent(serviceName);
                log.info("==> SpringCloud Gateway: The microservice {}[{}] instance is refreshed!", serviceName, present);
            }

            event.getHosts().stream().forEach(host -> {
                String ip = host.getIp();
                int port = host.getPort();
                String body = HttpRequest.get("http://" + ip + ":" + port + WarmUpConstant.WARM_UP)
                        .header(HeaderUtil.getFeignHeaderList())
                        .execute().body();
                log.warn("==> The {} instance warm up result: {}", serviceName, body);
            });
        }
    }

    @Override
    public Class<? extends com.alibaba.nacos.common.notify.Event> subscribeType() {
        return InstancesChangeEvent.class;
    }

}
